Added macros and counters to page table flushes.
macros and the counter are in a new header file -- flushtlb.h
3e20b82fl1jmQiKdLy7fxMcutfpjWA xen-2.4.16/include/asm-i386/domain_page.h
3ddb79c2O729EttZTYu1c8LcsUO_GQ xen-2.4.16/include/asm-i386/elf.h
3ddb79c3NU8Zy40OTrq3D-i30Y3t4A xen-2.4.16/include/asm-i386/fixmap.h
+3e2d29944GI24gf7vOP_7x8EyuqxeA xen-2.4.16/include/asm-i386/flushtlb.h
3ddb79c39o75zPP0T1aQQ4mNrCAN2w xen-2.4.16/include/asm-i386/hardirq.h
3ddb79c3BFEIwXR4IsWbwp4BoL4DkA xen-2.4.16/include/asm-i386/hdreg.h
3ddb79c3TMDjkxVndKFKnGiwY0HzDg xen-2.4.16/include/asm-i386/i387.h
#include <xeno/dom0_ops.h>
#include <asm/io.h>
#include <asm/domain_page.h>
+#include <asm/flushtlb.h>
rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
/* Install the new page tables. */
__cli();
- __asm__ __volatile__ (
- "mov %%eax,%%cr3" : : "a" (pagetable_val(p->mm.pagetable)));
+ __write_cr3_counted(pagetable_val(p->mm.pagetable));
/* Copy the guest OS image. */
src = (char *)__va(mod[0].mod_start + 12);
}
/* Reinstate the caller's page tables. */
- __asm__ __volatile__ (
- "mov %%eax,%%cr3" : : "a" (pagetable_val(current->mm.pagetable)));
+ __write_cr3_counted(pagetable_val(current->mm.pagetable));
__sti();
new_thread(p,
#include <xeno/sched.h>
#include <xeno/errno.h>
#include <asm/page.h>
+#include <asm/flushtlb.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/domain_page.h>
if ( tlb_flush[smp_processor_id()] )
{
tlb_flush[smp_processor_id()] = 0;
- __asm__ __volatile__ (
- "movl %%eax,%%cr3" : :
- "a" (pagetable_val(current->mm.pagetable)));
+ __write_cr3_counted(pagetable_val(current->mm.pagetable));
}
return(0);
--- /dev/null
+/******************************************************************************
+ * flushtlb.h
+ *
+ * TLB flush macros that count flushes. Counting is used to enforce
+ * zero-copy safety, particularily for the network code.
+ *
+ * akw - Jan 21, 2003
+ */
+
+#ifndef __FLUSHTLB_H
+#define __FLUSHTLB_H
+
+#include <xeno/smp.h>
+
+unsigned long tlb_flush_count[NR_CPUS];
+//#if 0
+#define __read_cr3(__var) \
+ do { \
+ __asm__ __volatile ( \
+ "movl %%cr3, %0;" \
+ : "=r" (__var)); \
+ } while (0)
+//#endif
+
+#define __write_cr3_counted(__pa) \
+ do { \
+ __asm__ __volatile__ ( \
+ "movl %0, %%cr3;" \
+ :: "r" (__pa) \
+ : "memory"); \
+ tlb_flush_count[smp_processor_id()]++; \
+ } while (0)
+
+//#endif
+#define __flush_tlb_counted() \
+ do { \
+ unsigned int tmpreg; \
+ \
+ __asm__ __volatile__( \
+ "movl %%cr3, %0; # flush TLB \n" \
+ "movl %0, %%cr3; " \
+ : "=r" (tmpreg) \
+ :: "memory"); \
+ tlb_flush_count[smp_processor_id()]++; \
+ } while (0)
+
+#endif
+
#include <asm/processor.h>
#include <asm/fixmap.h>
#include <asm/bitops.h>
+#include <asm/flushtlb.h>
extern l2_pgentry_t idle0_pg_table[ENTRIES_PER_L2_PAGETABLE];
extern l2_pgentry_t *idle_pg_table[NR_CPUS];
extern void paging_init(void);
-#define __flush_tlb() \
- do { \
- unsigned int tmpreg; \
- \
- __asm__ __volatile__( \
- "movl %%cr3, %0; # flush TLB \n" \
- "movl %0, %%cr3; \n" \
- : "=r" (tmpreg) \
- :: "memory"); \
- } while (0)
+#define __flush_tlb() __flush_tlb_counted()
/* Flush global pages as well. */
+
+#define __pge_off() \
+ do { \
+ __asm__ __volatile__( \
+ "movl %0, %%cr4; # turn off PGE " \
+ :: "r" (mmu_cr4_features & ~X86_CR4_PGE)); \
+ } while (0)
+
+#define __pge_on() \
+ do { \
+ __asm__ __volatile__( \
+ "movl %0, %%cr4; # turn off PGE " \
+ :: "r" (mmu_cr4_features)); \
+ } while (0)
+
+
#define __flush_tlb_all() \
do { \
- unsigned int tmpreg; \
- \
- __asm__ __volatile__( \
- "movl %1, %%cr4; # turn off PGE \n" \
- "movl %%cr3, %0; # flush TLB \n" \
- "movl %0, %%cr3; \n" \
- "movl %2, %%cr4; # turn PGE back on \n" \
- : "=&r" (tmpreg) \
- : "r" (mmu_cr4_features & ~X86_CR4_PGE), \
- "r" (mmu_cr4_features) \
- : "memory"); \
+ __pge_off(); \
+ __flush_tlb_counted(); \
+ __pge_on(); \
} while (0)
#define __flush_tlb_one(__addr) \